<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件上传</title>
  <script src="../static/js/vue.global.js"></script>
  <script src="../static/js/axios.min.js"></script>
</head>
<body>
<div id="app">
  <div>
    <div>请先输入上传地址：</div>
    <input type="text" v-model="url">
  </div>

  <h1>单文件上传</h1>
  <input type="file" ref="file1" id="file1" @change="upload">
  <input type="range" v-model="progress1" min="0" max="100"> {{progress1}}

  <h1>多文件上传</h1>
  <input type="file" ref="file2" id="file2" multiple @change="upload2">
  <input type="range" v-model="progress2" min="0" max="100"> {{progress2}}

  <h1>大文件分片上传</h1>
  <input type="file" ref="file3" id="file3" multiple @change="upload3">
  <input type="range" v-model="progress3" min="0" max="100"> {{progress3}}
</div>
<script>
  const { createApp } = Vue;
  createApp({
    data() {
      return {
        url: 'https://jsonplaceholder.typicode.com/posts/',
        progress1: 0,
        progress2: 0,
        progress3: 0,
      }
    },
    methods: {
      upload() {
        const file = this.$refs.file1.files[0];
        const formdata = new FormData();
        let _this = this;
        formdata.append('file', file);
        formdata.append('name', file.name);
        axios.post(this.url, formdata, {
          withCredentials: true,
          onUploadProgress: function(progress) {
            console.log(progress);
            _this.progress1 = progress.loaded/progress.total * 100
          }
        }).then(res => {
          alert('success')
        }).catch(err => {
          alert('fail')
        })
      },
      upload2() {
        const files = this.$refs.file2.files;
        const formdata = new FormData();
        let _this = this;

        // files是FileList对象，只有length和item方法，不支持forEach遍历
        for(let i =0; i<files.length; i++) {
          formdata.append('file', files[i]);
          formdata.append('name', files[i].name);
        }

        axios.post(this.url, formdata, {
          withCredentials: true,
          onUploadProgress: function(progress) {
            _this.progress2 = progress.loaded/progress.total * 100
          }
        }).then(res => {
          alert('success')
        }).catch(err => {
          alert('fail')
        })
      },
      upload3() {
        const file = this.$refs.file3.files[0];
        const DefaultChunkSize = 5 * 1024 * 1024;
      },
      // 分片
      handleFileChunk(file, chunkSize) {
        const fileChunkList = [];
        let curIndex = 0;
        while(curIndex<file.size) {
          const endIndex = curIndex + chunkSize < file.size ? curIndex + chunkSize : file.size;
          const curFileChunkFile = file.slice(curIndex, endIndex);
          curIndex += chunkSize;
          fileChunkList.push({file: curFileChunkFile})
        };
        return fileChunkList
      },
      async startUpload(bigFile, DefaultChunkSize) {
        const fileList = this.handleFileChunk(bigFile, DefaultChunkSize);
        const containerHash = await this.getFileHash2(bigFile);
        const chunksInfo = fileList.map(({file}, index) => ({
          fileHash: containerHash,
          hash: containerHash + '_' + index,
          index,
          fileCount: fileList.length,
          chunk: file,
          totalSize: bigFile.size,
          size: file.size
        }))
        this.uploadChunks(chunksInfo, bigFile.name)
      },
      getFileHash(fileList) {
        console.time('filehash');
        const spark = new SparkMD5.ArrayBuffer();
        const result => fileList.map((item, key) => {
          return this.getFileContent(item.file)
        })
      },
      uploadChunks() {

      },
      getFileContent() {

      }
    }
  }).mount('#app')
</script>
</body>
</html>
